package com.fz.us.admin.company.service.impl;

import com.fz.us.admin.base.bean.BaseEnumManager;
import com.fz.us.admin.base.bean.search.order.Order;
import com.fz.us.admin.base.bean.search.rule.Rule;
import com.fz.us.admin.base.bean.search.rule.RuleHelper;
import com.fz.us.admin.base.service.impl.BaseServiceImpl;

import com.fz.us.admin.base.bean.Result;
import com.fz.us.admin.base.bean.search.SearchEnum;
import com.fz.us.admin.base.bean.search.page.PagePaging;
import com.fz.us.admin.base.bean.search.result.SearchResultList;
import com.fz.us.admin.base.bean.search.result.SearchResultPaging;
import com.fz.us.admin.base.dao.BaseDao;
import com.fz.us.admin.company.dao.PowerDao;
import com.fz.us.admin.company.entity.*;

import com.fz.us.admin.company.service.DutyService;
import com.fz.us.admin.company.service.PowerService;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;

/**
 * Service实现类 - 职权
 * ============================================================================
 * 版权所有 2016 。
 *
 * @author fallenpanda
 * @version 1.0 2016-08-11 。
 * ============================================================================
 */
@Service
public class PowerServiceImpl extends BaseServiceImpl<Power, String> implements PowerService {

    @Resource
    private PowerDao powerDao;
    @Override
    public BaseDao<Power, String> getBaseDao() {
        return powerDao;
    }

    @Resource
    private DutyService dutyService;

    @Override
    public List<Power> getByDepartId(String departId) {
        return powerDao.getByDepartId(departId);
    }

    @Override
    public Power getPowerByDepartAndPost(Department department, Post post) {
        return powerDao.getPowerByDepartAndPost(department, post);
    }

    @Override
    public Set<Duty> findParentByPower(Duty duty) {
        Power power = duty.getPower();
        Set<Duty> dutySet = Sets.newHashSet();
        if(power.getParent()==null){
            return dutySet;
        }
        List<Duty> dutyList = dutyService.getDutyListByPower(power.getParent());
        dutySet.addAll(dutyList);
        return dutySet;
    }

    @Override
    public List<Power> getAllPowers(Company company) {
        return powerDao.getAllPowers(company);
    }

    @Override
    public List<Power> getRootPowers(Company company) {
        return powerDao.getRootPowers(company);
    }

    @Override
    public List<Power> getPowers(Company company, Power power) {
        return powerDao.getPowers(company, power);
    }

    @Override
    public List<Power> getLevelPowers(Company company, Department department) {
        return powerDao.getLevelPowers(company, department);
    }

    @Override
    public boolean isParentPower(Power power) {
        return powerDao.isParentPower(power);
    }

    @Override
    public boolean hasPost(Post post) {
        return powerDao.hasPost(post);
    }

    @Override
    public boolean hasDepartment(Department department) {
        return powerDao.hasDepartment(department);
    }



    @Override
    public List<Map<String, Object>> getTreeMapList(Company company) {
        return recursivTreeMapList(getAllPowers(company), null);
    }

    @Override
    public List<Map<String, Object>> getLevelTreeMapList(Company company, Department department, Power exceptPower) {
        List<Power> powerList = getLevelPowers(company, department);
        if (exceptPower != null && powerList.contains(exceptPower)) {
            powerList.remove(exceptPower);
        }
        return recursivTreeMapList(powerList, null);
    }

    /**
     * 递归职权 返回 Tree结构
     *
     * @param powerList
     * @param parent
     * @return
     */
    private List<Map<String, Object>> recursivTreeMapList(List<Power> powerList, Power parent) {
        List<Map<String, Object>> powerTreeList = new ArrayList<Map<String, Object>>();
        if (powerList != null && powerList.size() > 0) {
            for (Power power : powerList) {
                Power parentPower = power.getParent();
                if ((parent == null && parentPower == null) || (parent != null && parentPower != null && parent.equals(parentPower))) {
                    Map<String, Object> tempMap = new HashMap<String, Object>();
                    tempMap.put("id", StringUtils.isEmpty(power.getId())?"":power.getId());
                    tempMap.put("name", power.getDepartment()==null||power.getPost()==null?"":power.getDepartment().getName() + " - " + power.getPost().getName());
                    tempMap.put("children", recursivTreeMapList(powerList, power));
                    powerTreeList.add(tempMap);
                }
            }
        }
        return powerTreeList;
    }

    @Override
    public Result createEntity(User user, Power power) {
        Assert.notNull(user, "user is required");
        Assert.notNull(power, "power is required");
        Assert.notNull(power.getDepartment(), "department is required");
        Assert.notNull(power.getPost(), "post is required");

        Company company = user.getCompany();
        if (company == null)
            return resultService.fail("操作人没有所属企业");

        // 设置所属企业
        power.setCompany(company);

        return saveEntity(power);
    }

    @Override
    public Result updateEntity(User user, String keyId, Power power) {
        Assert.notNull(user, "user is required");
        Assert.hasText(keyId, "keyId is required");
        Assert.notNull(power, "power is required");
        Assert.notNull(power.getPost(), "post is required");

        Company company = user.getCompany();
        if (company == null)
            return resultService.fail("操作人没有所属企业");

        Power powerTemp = get(keyId);


        powerTemp.setPost(power.getPost());
        powerTemp.setParent(power.getParent());

        update(powerTemp);
        return resultService.successWithId(powerTemp.getId());
    }

    @Override
    public Result methodEntity(User user, String method, String keyId) {
        Assert.notNull(user, "user is required");
        Assert.hasText(method, "method is required");
        Assert.hasText(keyId, "keyId is required");

        Power power = get(keyId);
        if (power != null) {
            if (StringUtils.equals("Delete", method)) {// 删除
                // 是否已分配人员
                if (dutyService.hasPower(power)) {
                    return resultService.fail("职权已分配人员,请先移除");
                }

                // 是否存在下级职权
                if (isParentPower(power)) {
                    return resultService.fail("存在下级职权,请先取消关联");
                }

                return methodEntity(BaseEnumManager.MethodEnum.Delete, keyId);
            }
        }

        return resultService.fail();
    }

    @Override
    public SearchResultPaging pagingPower(PagePaging page, List<Rule> rules, Order order, Company company, Department department, BaseEnumManager.StateEnum... states) {
        Assert.notNull(company, "company is required");

        if (rules == null)
            rules = new ArrayList<Rule>();
        rules.add(RuleHelper.eq("company", company));
        if (department != null)
            rules.add(RuleHelper.eq("department", department));
        if (states != null && states.length > 0) {
            rules.add(RuleHelper.in("state", states));
        }

        // 默认排序
        if (order == null)
            order = Order.order("post.sortNo", SearchEnum.OrderType.asc);

        return findPagingBySearch(page, rules, order);
    }

    @Override
    public SearchResultPaging pagingAllPower(PagePaging page, List<Rule> rules, Order order, Company company, Department department, BaseEnumManager.StateEnum... states) {
        Assert.notNull(company, "company is required");
        Assert.notNull(department, "department is required");

        if (rules == null)
            rules = new ArrayList<Rule>();
        rules.add(RuleHelper.eq("company", company));
        rules.add(RuleHelper.or(
                RuleHelper.eq("department", department),
                RuleHelper.like("department.path", department.getId())
        ));
        if (states != null && states.length > 0) {
            rules.add(RuleHelper.in("state", states));
        }

        // 默认排序
        if (order == null)
            order = Order.order("post.sortNo", SearchEnum.OrderType.asc);

        return findPagingBySearch(page, rules, order);
    }

    @Override
    public SearchResultList listPower(List<Rule> rules, Order order, Company company, Department department, Power parent, BaseEnumManager.StateEnum... states) {
        Assert.notNull(company, "company is required");

        if (rules == null)
            rules = new ArrayList<Rule>();
        rules.add(RuleHelper.eq("company", company));
        if (department != null)
            rules.add(RuleHelper.eq("department", department));
        if (parent != null)
            rules.add(RuleHelper.eq("parent", parent));
        if (states != null && states.length > 0) {
            rules.add(RuleHelper.in("state", states));
        }

        // 默认排序
        if (order == null)
            order = Order.order("post.sortNo", SearchEnum.OrderType.asc);

        return findListBySearch(rules, order);
    }

    @Override
    public Map<String, Object> getListMap(Power power) {
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("id", StringUtils.isEmpty(power.getId())?"":power.getId());

        map.put("parentId", "");
        map.put("parentName", "");
        if (power.getParent() != null) {
            Power parent = power.getParent();
            map.put("parentId", parent.getId());
            map.put("parentName", parent.getDepartment().getName() + " - " + parent.getPost().getName());
        }

        map.put("departmentId", "");
        map.put("departmentName", "");
        map.put("departmentPinYinHead", "");
        map.put("departmentPinYin", "");
        if (power.getDepartment() != null) {
            Department department = power.getDepartment();
            map.put("departmentId", department.getId());
            map.put("departmentName", department.getName());
            map.put("departmentPinYinHead", department.getPinYinHead());
            map.put("departmentPinYin", department.getPinYin());
        }
        map.put("name", "");
        map.put("postId", "");
        map.put("postName", "");
        map.put("postPinYinHead", "");
        map.put("postPinYin", "");
        if (power.getPost() != null) {
            Post post = power.getPost();
            map.put("postId", post.getId());
            map.put("postName", post.getName());
            map.put("postPinYinHead", post.getPinYinHead());
            map.put("postPinYin", post.getPinYin());
        }
        if (power.getDepartment() != null && power.getPost() != null) {
            map.put("name", power.getDepartment().getName()+ " - " + power.getPost().getName());
        }


       // map.put("type", power.getType()==null?"":power.getType().name());

        // other
        map.put("state", power.getState()==null?"":power.getState().name());

        return map;
    }

    @Override
    public Map<String, Object> getDetailMap(Power power) {
        return getListMap(power);
    }

    @Override
    public Map<String, Object> getTreeMap(Power power) {
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("id", StringUtils.isEmpty(power.getId())?"":power.getId());
        map.put("name", power.getDepartment()==null||power.getPost()==null?"":power.getDepartment().getName() + " - " + power.getPost().getName());

        map.put("isParent", isParentPower(power));

        return map;
    }

    @Override
    //要舍弃
    public Power getPowerByValue(Company company, String value) {
        return powerDao.getPowerByValue(company, value);
    }
}
